<script lang="ts" setup>
  import { ref, computed, nextTick, PropType } from 'vue'
  import { Column } from './type'
  // import { saveListSetting } from '@/api/system/user'
  import Sortable from 'sortablejs'
  import { cloneDeep } from 'lodash-es'
  import { propTypes } from '@/utils/propTypes'
  import _ from 'lodash-es'
import { ElMessage } from 'element-plus'
  defineOptions({ name: 'TableSettingDialog' })

  const emit = defineEmits(['apply'])

  const props = defineProps({
    uniqueKey: {
      type: String,
      default: ''
    },
    // 表格列配置后数据
    configData: {
      type: Array as PropType<Column[]>,
      default: () => []
    },
    saveListSettingFunc: propTypes.func.def(undefined) // 保存表格配置
  })

  // 弹窗配置数据
  const dialogData = ref<Column[]>([])

  // 弹窗是否显示
  const dialogVisible = ref(false)

  // 重置数据
  const initData = ref<Column[]>([])

  const resetColumns = () => {
    dialogData.value = cloneDeep(initData.value)
      .filter((item: Column) => item.prop)
      .map((col: Column) => {
        return { ...col, show: col.show !== false ? true : false }
      })
  }

  // 打开弹窗
  const openDialog = (tableHeader: Column[]) => {
    initData.value = tableHeader
    dialogVisible.value = true
    dialogData.value = _.cloneDeep(props.configData)
      .filter((item: Column) => item.prop)
      .map((item: Column) => ({
        ...item,
        show: item.show === undefined ? true : item.show
      }))
    nextTick(() => initDialogTableSortable())
  }

  // 弹窗表格引用
  const eFilterSearchRef = ref()
  // 初始化表格拖拽排序
  const initDialogTableSortable = () => {
    nextTick(() => {
      const el = eFilterSearchRef.value
      if (!el) return

      Sortable.create(el, {
        animation: 300,
        handle: '.search-list',
        ghostClass: 'sortable-ghost',
        onEnd: ({ newIndex, oldIndex }) => {
          if (newIndex === undefined || oldIndex === undefined) return
          const newData = [...dialogData.value]
          const [moved] = newData.splice(oldIndex, 1)
          newData.splice(newIndex, 0, moved)
          dialogData.value = newData
        }
      })
    })
  }

  // 应用设置
  const saveLoading = ref(false)
  const applyColumns = () => {
    saveLoading.value = true
    // 保存时重置排序号
    let settingValue = dialogData.value.map((col, index) => ({ ...col, sortNo: index }))
    // 保存列表设置到服务器
    props.saveListSettingFunc?.({
      settingKey: props.uniqueKey,
      settingValue: _.cloneDeep(settingValue)
    })
      .then((res:any) => {
        if (res) {
          ElMessage.success('保存成功')
          emit('apply', settingValue)
          dialogVisible.value = false
        } else {
          ElMessage.error('保存失败')
        }
      })
      .finally(() => {
        saveLoading.value = false
      })
  }

  // 过滤字段
  const settingField = computed(() => {
    return dialogData.value.filter((item: Column) => !item.hiddenSetting)
  })
  // 暴露方法给父组件
  defineExpose({
    openDialog
  })
</script>

<template>
  <Dialog v-model="dialogVisible" title="列表设置" append-to-body width="400px">
    <div class="e-filter-search" ref="eFilterSearchRef">
      <div v-for="item in settingField" :key="item.prop" class="search-list">
        <div class="search-list-item flex items-center justify-between">
          <span class="flex items-center">
            <Icon style="margin-right: 10px" icon="ep:operation" />
            {{ item.label }}
          </span>
          <span class="flex cursor-pointer items-center">
            <Icon @click="item.show = !item.show" v-if="item.show" icon="ep:view" />
            <Icon @click="item.show = !item.show" v-else icon="ep:hide" />
          </span>
        </div>
      </div>
    </div>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="saveLoading" @click="applyColumns">确定</el-button>
        <el-button type="primary" @click="resetColumns">重置</el-button>
      </span>
    </template>
  </Dialog>
</template>

<style lang="scss" scoped>
  :deep(.el-table__row) {
    cursor: move;
  }

  :deep(.sortable-ghost) {
    opacity: 0.5;
    background: #a8abb2;
  }
  .e-filter-search {
    .search-list {
      &:nth-child(odd) {
        background-color: #f8fafe;
      }
      .search-list-item {
        height: 23px;
        padding: 12px;
      }
    }
  }
</style>
